from tortoise.transactions import in_transaction

from app.model import mysql
from app.service.folder import incr_media_number
from app.service.search import index_my_media


async def remove_user_recycle(recycle_id: int):
    """
    删除回收站一条数据
    :param recycle_id:
    :return:
    """
    async with in_transaction("default") as tconn:
        await mysql.RecycleBin.filter(id=recycle_id).using_db(tconn).delete()


async def remove_user_recycles(recycle_ids: list):
    """
    删除回收站N条数据
    :param recycle_ids:
    :return:
    """
    for recycle_id in recycle_ids:
        await remove_user_recycle(recycle_id)


async def remove_user_all_recycle(user_id: int):
    """
    清空回收站
    :param user_id:
    :return:
    """
    async with in_transaction("default") as tconn:
        await mysql.RecycleBin.filter(user_id=user_id).using_db(tconn).delete()


async def restore_recycle(recycle_id: int, folder_id: int = 0):
    """
    恢复回收站一条数据
    :param recycle_id:
    :param folder_id: 有值 则强制恢复到此文件夹
    :return: 是否恢复成功, 0-成功 1-未找到文件夹 2-媒体文件丢失（一般不会出现）
    """
    recycle = await mysql.RecycleBin.get_or_none(id=recycle_id)
    if not recycle:
        return 0
    need_folder_id = folder_id or recycle.folder_id
    folder = await mysql.Folder.get_or_none(id=need_folder_id)
    if not folder:
        return 1
    media = await mysql.Media.get_or_none(id=recycle.media_id)
    if not media:
        return 2
    async with in_transaction("default") as tconn:
        # 文件夹文件新增
        await mysql.FolderFile.get_or_create(
            id=recycle.id,
            defaults={
                'folder_id': need_folder_id,
                'media_id': recycle.media_id,
                'user_id': recycle.user_id,
                'created_time': recycle.created_time
            },
            using_db=tconn,
        )
        # 更新文件夹媒体个数
        await incr_media_number(need_folder_id, incr=1, conn=tconn)
        # 删除此回收站信息
        await mysql.RecycleBin.filter(id=recycle_id).using_db(tconn).delete()
        # 恢复我的图片数据
        await mysql.MyMedia.get_or_create(
            user_id=recycle.user_id,
            media_id=recycle.media_id,
            defaults={'created_time': recycle.created_time},
            using_db=tconn,
        )
        # 如果是自己的媒体，则改为未删除状态
        if media.is_delete and media.user_id == recycle.user_id:
            await mysql.Media.filter(id=recycle.media_id).using_db(tconn).update(is_delete=False)
    # 索引(不存在则删除)
    await index_my_media(recycle.user_id, recycle.media_id)
    return 0


async def restore_recycles(recycle_ids: list, folder_id: int = 0):
    """
    恢复回收站一组数据
    :param recycle_ids:
    :param folder_id:
    :return:
    """
    success_ids = []
    fail_ids = []
    for recycle_id in recycle_ids:
        status = await restore_recycle(recycle_id, folder_id=folder_id)
        if status in [1, 2]:
            fail_ids.append(recycle_id)
        elif status == 0:
            success_ids.append(recycle_id)
    return success_ids, fail_ids


async def get_user_recycles(user_id: int, offset: int = 0, limit: int = 10):
    """
    获取回收站媒体信息
    :param user_id:
    :param offset:
    :param limit:
    :return:
    """
    recycles = await mysql.RecycleBin.filter(user_id=user_id).order_by('-deleted_time').offset(offset).limit(limit)
    return recycles


async def get_user_recycle_count(user_id: int):
    """
    获取回收站媒体个数
    :param user_id:
    :return:
    """
    return await mysql.RecycleBin.filter(user_id=user_id).count()
